package main

import (
	"bytes"
	"context"
	"fmt"
	"gitee.com/jinmingzhi/eth-learn/pkg/ethtool"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"math/big"
)

// 私钥
var (
	url = "http://localhost:8545"
	hex = "0xebbe69fb9ddc6bff8d668617639f131bc2cfb3a184bb194ce949a1b0dbbfa3a5" //private key
)

func main() {
	credential, err := ethtool.HexToCredential(hex)
	assert(err)
	fmt.Println("address:", credential.Address.Hex())

	ctx := context.Background()
	client, err := ethtool.Dial(url)
	assert(err)

	chainId, err := client.NetVersion(ctx)
	assert(err)
	fmt.Println("chainID:", chainId) // 链ID

	nonce, err := client.EthGetTransactionCount(ctx, credential.Address, "pending")
	assert(err)
	fmt.Println("nonce:", nonce)

	// 创建新的账户
	toAddress := NewCredential()
	tx := types.NewTx(&(types.LegacyTx{
		Nonce:    nonce,
		To:       &toAddress,
		Value:    ethtool.ToWei(big.NewFloat(5.2), ethtool.Ether),
		Gas:      uint64(21000), // gas 上线
		GasPrice: big.NewInt(2e9),
		Data:     nil,
	}))

	// 签名
	signer := types.LatestSignerForChainID(chainId)
	signedTx, err := types.SignTx(tx,signer,credential.PrivateKey)
	//signedTx, err := credential.SignTx(tx, chainId)
	assert(err)
	fmt.Println("signedTx: ", signedTx)

	buf := new(bytes.Buffer)
	err = signedTx.EncodeRLP(buf)
	assert(err)

	txId, err := client.EthSendRawTransaction(ctx, buf.Bytes())
	assert(err)
	fmt.Println("raw tx id:", txId)

	balance, err := client.EthGetBalance(ctx, credential.Address, "latest")
	assert(err)
	fmt.Printf("form address: %s, balace#latest:%d \n", credential.Address.Hex(), ethtool.FromWei(balance, ethtool.Ether))

	balance, err = client.EthGetBalance(ctx, toAddress, "latest")
	assert(err)
	fmt.Printf("to address: %s, balace#latest:%d \n", credential.Address.Hex(), ethtool.FromWei(balance, ethtool.Ether))

}

func assert(err error) {
	if err != nil {
		panic(err)
	}
}

func NewCredential() (address common.Address) {
	fmt.Println("----- new credential ------")
	credential, err := ethtool.NewCredential()
	assert(err)
	fmt.Println("private key: ", credential.PrivateKeyHex())
	fmt.Println("public key: ", credential.PublicKeyHex())
	fmt.Println("address: ", credential.AddressHex())
	return credential.Address
}
